// 日志工具函数
function log(level, message, data = null) {
    const timestamp = new Date().toISOString();
    const logMessage = `[${timestamp}] [${level}] ${message}`;
    
    if (data) {
        console.log(logMessage, data);
    } else {
        console.log(logMessage);
    }
}

document.addEventListener('DOMContentLoaded', () => {
    const oldFileUpload = document.getElementById('oldFileUpload');
    const newFileUpload = document.getElementById('newFileUpload');
    const oldFileInput = document.getElementById('oldFile');
    const newFileInput = document.getElementById('newFile');
    const oldFileInfo = document.getElementById('oldFileInfo');
    const newFileInfo = document.getElementById('newFileInfo');
    const compareButton = document.getElementById('compareButton');
    const callChainButton = document.getElementById('callChainButton');
    const progressBar = document.getElementById('progressBar');
    const progressText = document.getElementById('progressText');
    const resultContainer = document.getElementById('resultContainer');
    const resultContent = document.getElementById('resultContent');
    const packagePrefixInput = document.getElementById('packagePrefix');

    let oldFile = null;
    let newFile = null;

    // 文件拖拽处理
    function handleDragOver(e) {
        e.preventDefault();
        e.stopPropagation();
        e.currentTarget.querySelector('.file-upload-box').classList.add('dragover');
    }

    function handleDragLeave(e) {
        e.preventDefault();
        e.stopPropagation();
        e.currentTarget.querySelector('.file-upload-box').classList.remove('dragover');
    }

    function handleDrop(e, fileInput) {
        e.preventDefault();
        e.stopPropagation();
        e.currentTarget.querySelector('.file-upload-box').classList.remove('dragover');

        const files = e.dataTransfer.files;
        if (files.length > 0 && files[0].name.endsWith('.jar')) {
            fileInput.files = files;
            handleFileSelect(fileInput);
        }
    }

    // 文件选择处理
    function handleFileSelect(input) {
        const file = input.files[0];
        if (!file) return;

        log('INFO', `文件已选择: ${file.name}`, {
            size: `${(file.size / (1024 * 1024)).toFixed(2)} MB`,
            type: file.type,
            lastModified: new Date(file.lastModified).toISOString()
        });

        const fileInfo = input.id === 'oldFile' ? oldFileInfo : newFileInfo;
        const fileSize = (file.size / (1024 * 1024)).toFixed(2);

        fileInfo.innerHTML = `
            <div class="file-details">
                <strong>文件名:</strong> ${file.name}<br>
                <strong>大小:</strong> ${fileSize} MB
            </div>
        `;

        if (input.id === 'oldFile') {
            oldFile = file;
            log('DEBUG', '更新oldFile');
        } else {
            newFile = file;
            log('DEBUG', '更新newFile');
        }

        updateCompareButton();
    }

    function updateCompareButton() {
        const hasFiles = oldFile && newFile;
        compareButton.disabled = !hasFiles;
        // 调用链分析按钮默认禁用，只有在比对完成后才启用
        callChainButton.disabled = true;
    }

    // 比对处理
    async function handleCompare() {
        if (!oldFile || !newFile) {
            log('ERROR', '文件未完整选择', { oldFile: !!oldFile, newFile: !!newFile });
            return;
        }

        const packagePrefix = packagePrefixInput.value.trim();
        if (!packagePrefix) {
            log('WARN', '包前缀为空');
            alert('请输入包前缀');
            packagePrefixInput.focus();
            return;
        }

        log('INFO', '开始比对', {
            oldFile: oldFile.name,
            newFile: newFile.name,
            packagePrefix: packagePrefix
        });

        const formData = new FormData();
        formData.append('oldJar', oldFile);
        formData.append('newJar', newFile);
        formData.append('packagePrefix', packagePrefix);

        // 显示进度条和结果容器
        resultContainer.style.display = 'block';
        progressBar.style.width = '0%';
        progressText.textContent = '0%';
        resultContent.innerHTML = '<div class="loading">正在比对中...</div>';

        try {
            log('DEBUG', '发送比对请求');
            const response = await fetch('/compare', {
                method: 'POST',
                body: formData
            });

            if (!response.ok) {
                throw new Error(`HTTP错误! 状态: ${response.status}`);
            }

            const result = await response.json();
            log('INFO', '收到比对结果', result);
            showComparisonResults(result);
            
        } catch (error) {
            log('ERROR', '比对失败', error);
            resultContent.innerHTML = `<div class="error">比对失败: ${error.message}</div>`;
        }
    }

    function showComparisonResults(result) {
        log('DEBUG', '开始处理比对结果');
        progressBar.style.width = '100%';
        progressText.textContent = '100%';

        // 确保result对象及其属性存在
        const addedCount = result?.addedClasses?.length || 0;
        const deletedCount = result?.deletedClasses?.length || 0;
        const modifiedCount = result?.modifiedClasses?.length || 0;
        const classDiffs = result?.classDiffs || {};

        let html = `
            <div class="comparison-summary">
                <h3>比对完成</h3>
                <p>旧版本: ${oldFile.name}</p>
                <p>新版本: ${newFile.name}</p>
                <p>包前缀: ${packagePrefixInput.value}</p>
                <div class="diff-details">
                    <p>新增类: ${addedCount}</p>
                    <p>删除类: ${deletedCount}</p>
                    <p>修改类: ${modifiedCount}</p>
                </div>
                <div class="modified-classes">
                    ${formatClassDiffs(classDiffs)}
                </div>
            </div>
        `;

        resultContent.innerHTML = html;
        log('INFO', '比对结果已显示');
        
        // 添加按钮事件监听
        addEventListeners();
    }

    function formatClassDiffs(classDiffs) {
        if (!classDiffs || Object.keys(classDiffs).length === 0) {
            return '<p>没有发现类的变更</p>';
        }

        let html = '<div class="class-changes">';
        Object.entries(classDiffs).forEach(([className, classDiff]) => {
            html += `
                <div class="class-change">
                    <div class="class-header">
                        <span class="class-name">${className}</span>
                        <button class="toggle-methods-btn" data-class="${className}">
                            <span class="toggle-icon">▼</span>
                        </button>
                    </div>
                    <div class="method-list" id="methods-${className}">
                        ${formatMethodDiffs(classDiff.methodDiffs, className)}
                    </div>
                </div>
            `;
        });
        html += '</div>';
        return html;
    }

    function formatMethodDiffs(methodDiffs, className) {
        if (!methodDiffs || methodDiffs.length === 0) {
            return '<p class="no-methods">没有方法变更</p>';
        }

        let html = '';
        methodDiffs.forEach(method => {
            const methodId = `${className}-${method.methodName}`;
            html += `
                <div class="method-change">
                    <div class="method-header">
                        <span class="method-name">${method.methodName}</span>
                        <span class="method-signature">${method.methodSignature}</span>
                        <div class="method-actions">
                            <span class="change-type">${Array.from(method.changes).join(', ')}</span>
                            <button class="analyze-chain-btn" data-method="${className}.${method.methodName}">分析调用链</button>
                        </div>
                    </div>
                    <div class="call-chain-container" id="chain-${methodId}"></div>
                </div>
            `;
        });
        return html;
    }

    function addEventListeners() {
        // 添加类展开/折叠按钮的事件监听
        document.querySelectorAll('.toggle-methods-btn').forEach(button => {
            button.addEventListener('click', () => {
                const className = button.getAttribute('data-class');
                const methodList = document.getElementById(`methods-${className}`);
                const icon = button.querySelector('.toggle-icon');
                
                if (methodList.style.display === 'none') {
                    methodList.style.display = 'block';
                    icon.textContent = '▼';
                } else {
                    methodList.style.display = 'none';
                    icon.textContent = '▶';
                }
            });
        });

        // 添加调用链分析按钮的事件监听
        document.querySelectorAll('.analyze-chain-btn').forEach(button => {
            button.addEventListener('click', () => {
                const methodName = button.getAttribute('data-method');
                handleCallChainAnalysis(methodName);
            });
        });
    }

    function showCallChainResults(result, methodName) {
        const [className, methodNameOnly] = methodName.split('.');
        const methodId = `${className}-${methodNameOnly}`;
        const container = document.getElementById(`chain-${methodId}`);
        if (!container) return;

        let html = '<div class="call-chain-results">';
        const chains = result?.callChains?.[methodName] || [];
        
        if (chains.length === 0) {
            html += '<p>未找到调用链</p>';
        } else {
            html += '<ul class="call-chains">';
            chains.forEach((chain, index) => {
                const nodes = chain?.nodes || [];
                const path = nodes.map(node => `${node?.className || ''}.${node?.methodName || ''}`).join(' → ');
                html += `
                    <li class="call-chain">
                        <span class="chain-number">#${index + 1}</span>
                        <span class="chain-path">${path}</span>
                    </li>
                `;
            });
            html += '</ul>';
        }
        html += '</div>';
        
        container.innerHTML = html;
    }

    async function handleCallChainAnalysis(methodName) {
        if (!oldFile || !newFile) {
            alert('请选择JAR文件');
            return;
        }

        const formData = new FormData();
        formData.append('oldJarFile', oldFile);
        formData.append('newJarFile', newFile);
        formData.append('changedMethod', methodName);

        try {
            log('DEBUG', '发送调用链分析请求');
            const response = await fetch('/compareWithCallChain', {
                method: 'POST',
                body: formData
            });

            if (!response.ok) {
                throw new Error(`HTTP错误! 状态: ${response.status}`);
            }

            const result = await response.json();
            log('INFO', '收到调用链分析结果', result);
            showCallChainResults(result, methodName);
            
        } catch (error) {
            log('ERROR', '调用链分析失败', error);
            alert('调用链分析失败: ' + error.message);
        }
    }

    // 事件监听器
    [oldFileUpload, newFileUpload].forEach(upload => {
        upload.addEventListener('dragover', handleDragOver);
        upload.addEventListener('dragleave', handleDragLeave);
    });

    oldFileUpload.addEventListener('drop', (e) => handleDrop(e, oldFileInput));
    newFileUpload.addEventListener('drop', (e) => handleDrop(e, newFileInput));

    oldFileInput.addEventListener('change', () => handleFileSelect(oldFileInput));
    newFileInput.addEventListener('change', () => handleFileSelect(newFileInput));

    compareButton.addEventListener('click', handleCompare);
    callChainButton.addEventListener('click', displayMethodDiffs);
});
